///////////////////////////////////////////////////////////////////////////////
//
// lighthouse3D - 3D Software Library
//
// File: C3DLibInterface.h
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003-2013 Marcus Reinhardt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
//
// You can find a copy of the GNU General Public License (gpl.txt) in the
// directory of the library.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef _C3DLibInterface_H_
#define _C3DLibInterface_H_

#include <string.h>

#include "C2DScreen.h"
#include "CFileHandler.h"
#include "CFogSynthesis.h"
#include "CLighting.h"
#include "CMathe3D.h"
#include "CMeshStorage.h"
#include "CObjects.h"
#include "CCamera.h"
#include "CZBuffer.h"

///////////////////////////////////////////////////////////////////////////////////
//  class C3DLibrary : Root class to handle the library
///////////////////////////////////////////////////////////////////////////////////

//! Root class to handle the library functions

class C3DLibInterface {

  public:
  
    ///////////////////////////////////////////////////////////////////////////////
    // constructor/destructor
    ///////////////////////////////////////////////////////////////////////////////
    C3DLibInterface();
    ~C3DLibInterface();

    void bindLibrary(C3DLibrary *pLibRef);
	bool checkBinding();

    ///////////////////////////////////////////////////////////////////////////////
    // library setup functions
    ///////////////////////////////////////////////////////////////////////////////
	void setupUseInternalScreen();
    void setupColDetection(int ColDetection);
    void setupBFCulling(int bfCulling);
    void setupFSAAFilter(int filter);
    void setupTexFilter(int filter);
    void setupLighting(int lighting);
    void setupRenderer(int renderer);
    void setupShader(int shader);
    void setupFogSynthesis(int fog);
    void setupIncShader();
    void setupLogo(int logo);

	///////////////////////////////////////////////////////////////////////////////
    // core function to rerender scene
    ///////////////////////////////////////////////////////////////////////////////
	bool update3DScene();

	///////////////////////////////////////////////////////////////////////////////
    // direct screen access
    ///////////////////////////////////////////////////////////////////////////////
    C2DScreen *getScreenHandle();
    void clear();
    void resizeScreen(int sX, int sY);
	unsigned int getPixel(int x, int y);
    unsigned int getPixelRelative(int x, int y, int relX, int relY);

    ///////////////////////////////////////////////////////////////////////////////
    // object factory
    ///////////////////////////////////////////////////////////////////////////////
    void setPlaneParams(float s, int ps);
    void setPyramidParams(float s);
    void setCubeParams(float s, bool tl, bool bl);
    void setCylinderParams(float h, float rt, float rc, int c);
    void setConeParams(float h, float r, int c);
    void setSphereParams(float c, float p, float r);
    void setHeightMapParams(float mX, float mY, int autoBal);
    bool createNewObject();
    bool finalizeNewObject();
    bool finalizeObject(int mesh);
    bool createPlane(const char *texname);
    bool createPyramid(const char *texname);
    bool createCube(const char *texname);
    bool createCylinder(const char *texname);
    bool createCone(const char *texname);
	bool createSphere(const char *texname);
    bool createSimpleSurface(const char *texname, const char *texname2,
                                              const char *texname3, const char *texname4, const char *texname5);
    bool createHeightMapSurface(const char *texname, const char *texname2);
	int  getLastObjectReference() { return pLibRef->getMeshCount()-1; };
	T3DPosition getObjectPosition(int mesh) { return pLibRef->getPositionMap(mesh); };
	void setObjectPosition(int mesh, T3DPosition posMap) { pLibRef->setPositionMap(mesh, posMap); };

    ///////////////////////////////////////////////////////////////////////////////
    // file functions
    ///////////////////////////////////////////////////////////////////////////////
	bool load3DSFile(const char *fname);
    bool loadOBJFile(const char *fname);
    bool getFileExtension(char *fname, char *ext);
    
    ///////////////////////////////////////////////////////////////////////////////
    // lighting functions
    ///////////////////////////////////////////////////////////////////////////////
	bool setAmbientLight(float i);
    bool addDotLight(float x, float y, float z, int r, int g, int b, float id, float is);
    bool setSpecularPower(int i);
	TLightSource *getDotLight(int i);
    bool setDotLight(int i, TLightSource &l);

    ///////////////////////////////////////////////////////////////////////////////
    // camera functions
    ///////////////////////////////////////////////////////////////////////////////
	bool addCamera(int rx, int ry, int rz, float tx, float ty, float tz, float cn, float cf);
    bool setActiveCamera(int i);
	void resetActiveCamera();
    bool setNextCamera();
    TCamera getActiveCameraInformation();

    ///////////////////////////////////////////////////////////////////////////////
    // camera control functions
    ///////////////////////////////////////////////////////////////////////////////
    bool moveAheadCamera(float speed);
    bool moveBackCamera(float speed);
    bool moveLeftCamera(float speed);
    bool moveRightCamera(float speed);
    bool moveUpCamera(float speed);
    bool moveDownCamera(float speed);
    bool turnUpCamera(int speed);
    bool turnDownCamera(int speed);
    bool turnLeftCamera(int speed);
    bool turnRightCamera(int speed);
    bool setColDistance(float d);

    ///////////////////////////////////////////////////////////////////////////////
    // library status
    ///////////////////////////////////////////////////////////////////////////////
    int getTrianglesCount();
    int getVertexCount();
    int getRenderedTrianglesCount();
    int getRenderedPixelsCount();
    int getRenderedHLinesCount();

    ///////////////////////////////////////////////////////////////////////////////
    // fog functions
    ///////////////////////////////////////////////////////////////////////////////
	void setFogSynthesis(float nd, float fd, float fdn, int r, int g, int b);

    ///////////////////////////////////////////////////////////////////////////////
    // graphical user interface primitives
    ///////////////////////////////////////////////////////////////////////////////
	bool loadFont(char *f);
    bool drawText(int x, int y, char *t);
    void drawBox(int x1, int y1, int x2, int y2, int y3, unsigned int c1, unsigned int c2, unsigned int c3);
    void setFontColor(unsigned int c);
    void drawGUIBox(int x1, int y1, int x2, int y2, int y3, unsigned int c1, unsigned int c2, unsigned int c3, char *t);
    void drawGUIStdBox(int x1, int y1, int x2, int y2, int y3, char *t);
    void setGUITransparency(float t);
    void setCaption(TGUIHandle *h, char *c);
    void setVisible(TGUIHandle *h, bool v);
    void updateGUIElements();
    bool isOverGUIElement(TGUIHandle *h, int x, int y);
    bool isOverNoGUIElement(int x, int y);
    bool setBackgroundPicture(char *f);
    bool saveSnapshot(char *f);

    ///////////////////////////////////////////////////////////////////////////////
    // graphical user interface elements
    ///////////////////////////////////////////////////////////////////////////////
    TGUIHandle *getMainHandle();
    TGUIHandle *createButton(TGUIHandle *handle, int x, int y, int w, int h, char *t);
    TGUIHandle *createWindow(TGUIHandle *handle, int x, int y, int w, int h, int h2, char *t);
    TGUIHandle *createLabel(TGUIHandle *handle, int x, int y, int c, char *t);

	///////////////////////////////////////////////////////////////////////////////
    // other functions
    ///////////////////////////////////////////////////////////////////////////////
    void release();

  private:

    // local reference to library
	C3DLibrary *pLibRef;

};

#endif
